#coding=utf-8
#!/usr/bin/python

'''
Created on 2012-11-17

@author: Neo.Chen
'''

'''
功能：定时检查me服务，如果发现某些房间没视频，就报警
'''


import os
import sys
import time
import string
import logging
import threading
import socket
import select
import http.client
import json
from ktlib import ktlib
from ktlib import kttlv

g_server_ip = "120.199.9.197"
g_server_port = 5401
g_recv_timeout = 30     #60秒超时
g_urm_host = "www.52le.com"

#g_server_ip = "192.168.104.44"
#g_urm_host = "192.168.101.128"

#房间错误次数列表，支持5000个房间
g_lstErrorRoom=[]
for i in range(0, 5000):
    g_lstErrorRoom.append(0)


def sendtlv(sock, cmd, data):
    head = kttlv.make_head(cmd, len(data)+12)
    tlv = head + data
    sock.send(tlv)

def onError(count, message):
    #小于5次不报警
    if count < 5:
        return

    if count == 0:
        str = "check me server resume! %s" % (message)
        strTitle = "resume video"
    else:
        str = "check me server error! count:%d, %s" % (count, message)
        strTitle = "no video %d" % (count)
    #发邮件通知
    ktlib.send_email("admin@sky-mobi.com", "neo.chen@sky-mobi.com", str, strTitle)
    ##ktlib.send_email("admin@sky-mobi.com", "18758166494@139.com", str, strTitle)
    ktlib.send_email("admin@sky-mobi.com", "tristan.yang@sky-mobi.com", str, strTitle)
    ktlib.send_email("admin@sky-mobi.com", "13958110295@139.com", str, strTitle)

    #华灿的邮箱
    ktlib.send_email("admin@sky-mobi.com", "13516772765@139.com", str, strTitle)

    #王英的邮箱
    #ktlib.send_email("admin@sky-mobi.com", "13906521913@139.com", str, strTitle)

    #写单独的日志文件
    ktlib.append_log("./mecheck_py.log", str)


def getActiveRoom():
    #使用全局变量
    global g_urm_host
    global g_urm_port
    roomids = []
    try:
        conn = http.client.HTTPConnection(g_urm_host)
        conn.request("GET", "/room!getRoomPop")
        r1 = conn.getresponse()
        print(r1.status, r1.reason)
        print(r1)
        data = r1.read()
        roominfo = bytes.decode(data)
        locations = json.loads(roominfo)
        for location in locations:
            status = location["status"]
            roomid = location["roomId"]
            roomName = location["roomName"]
            showerName = location["showerName"]
            if status == 2:
                print("roomid:%d, roomName:%s, showerNam:%s \r\n" % (roomid, roomName, showerName))
                roomids.append(roomid)
    except:
        print("connect urm error")
    return roomids

#是否有直播
def is_active_room(roomid):
    curids = getActiveRoom()
    for curid in curids:
        if roomid == curid:
            return True
    return False

#获取错误次数
def getErrorCount(roomid):
    global g_lstErrorRoom
    g_lstErrorRoom[roomid - 30000] = g_lstErrorRoom[roomid - 30000] + 1
    return g_lstErrorRoom[roomid - 30000]
#房间成功的处理
def OnRoomSuccess(roomid):
    global g_lstErrorRoom
    if g_lstErrorRoom[roomid - 30000] != 0:
        g_lstErrorRoom[roomid - 30000] = 0
        onError(0, "%d" % (roomid))

#检测主函数
def me_check():
    roomids = getActiveRoom()
    for roomid in roomids:
        key = "room:%d" % roomid
        check_result = check_room(key)
        if check_result == False:
            #再从首页检查一下，该房间是不是还直播，如果是，则认为确实是没视频的
            if is_active_room(roomid):
                count = getErrorCount(roomid)
                onError(count, key)
            else:
                OnRoomSuccess(roomid)
        else:
            OnRoomSuccess(roomid)
    print("me_ckeck success!")

def check_room(roomkey):
    #使用全局变量
    global g_server_ip
    global g_server_port
    global g_recv_timeout

    logging.info("me_check, entry, roomKey:%s" % (roomkey))
    conn = 0
    ts = socket.socket()
    try:
        ts.connect((g_server_ip, g_server_port))
        conn = 1
    except:
        ts.close()
        logging.warning("me_check, connect failed!")
    if conn != 1:
        return False

    strSkyid = "1234567788"

    #发送登录请求
    CMDNO_ME_CLIENT_LOGIN_REQ = 0x1001
    x1001_tag_skyid = 1
    x1001_tag_hsman = 4
    x1001_tag_hstype = 5
    x1001_tag_imsi = 6
    x1001_tag_imei = 7

    data = kttlv.encoder_string(x1001_tag_skyid, strSkyid) + \
        kttlv.encoder_string(x1001_tag_hsman, "sky") + \
        kttlv.encoder_string(x1001_tag_hstype, "MTK6236OTA") + \
        kttlv.encoder_string(x1001_tag_imsi, "imsi") + \
        kttlv.encoder_string(x1001_tag_imei, "imei")
    sendtlv(ts, CMDNO_ME_CLIENT_LOGIN_REQ, data)

    #发送点播请求
    CMDNO_CLIENT_SUB_MEDIA_REQ = 0x1002
    ST_ROOM_TLV= 0 + 4
    x1002_tag_skyid = 1
    x1002_tag_media_type = 2
    x1002_tag_resouce_id = 3
    x1002_tag_key_md5 = 4
    x1002_tag_media_quality = 5

    data = kttlv.encoder_string(x1002_tag_skyid, strSkyid) + \
        kttlv.encoder_int8(x1002_tag_media_type, ST_ROOM_TLV) + \
        kttlv.encoder_string(x1002_tag_resouce_id, "008") + \
        kttlv.encoder_string(x1002_tag_key_md5, roomkey) + \
        kttlv.encoder_int8(x1002_tag_media_quality, 1)
    sendtlv(ts, CMDNO_CLIENT_SUB_MEDIA_REQ, data)

    #接收10k数据，并将计数器增加
    #如果60秒没数据则报警
    tmStart = time.time()
    MAX_RECV_LEN = 10 *1024
    total_recv_len = 0
    while True:
        #如果接收视频数据超时了，则报警
        tmNow = time.time()
        if tmNow - tmStart > g_recv_timeout:
            break

        #接收数据
        rl,wl,xl = select.select([ts.fileno()],[],[ts.fileno()], 10)
        if len(xl) > 0:
            ts.close()
            print("socket closed.")
            break
        if len(rl) > 0:
            try:
                buffer = ts.recv(10000)
                data_len = len(buffer)
                if data_len == 0:
                    raise

                logging.debug("recv len:%d" % data_len)
                total_recv_len = total_recv_len + data_len
                if total_recv_len > MAX_RECV_LEN:
                    break
            except:
                ts.close()
                print("socket closed.")

    logging.info("me_check, exit")
    if total_recv_len > MAX_RECV_LEN:
        logging.info("recv success! len:%d" % total_recv_len)
        return True
    else:
        logging.warning("recv failed! len:%d" % total_recv_len)
        return False


def main():
    print("main start...")
    logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='mecheck.log',
                filemode='w')
    while True:
        logging.info("main, app check...")
        me_check()
        logging.info("main, app check end")
        time.sleep(60)

if __name__ == '__main__':
    ktlib.ForkMySelf("mecheck", 3)
    try:
        main()
    except:
        ktlib.write_crash_log()
